//---------------------------------------------------------------------------


#include "GrupoOpc.h"
#include <stdio.h>
#include <oaidl.h>

//---------------------------------------------------------------------------
WCHAR * WSTRFromSBCS(const CHAR *buf, IMalloc * pmem)
{
    int	length, i;
    WCHAR	*temp;

    length = strlen(buf) + 1;
    if(pmem) temp = (WCHAR*)pmem->Alloc(sizeof(WCHAR) * (strlen(buf) + 1));
    else temp = new WCHAR[strlen(buf) + 1];

    if(temp)
    {
        for(i=0; i<length; i++) temp[i] = (WCHAR) buf[i];
    }
    return temp;
}

/**
*  \brief	Construtor da classe.
*  \param XX
*
*/
GrupoOpc::GrupoOpc(char *nomeGrupo,int taxa,float dead,bool active,int tipo){
    this->nomeGrupo = nomeGrupo;
    this->taxa = taxa;
    this->dead = dead;
    this->active = active;
    this->tipo = tipo;
    this->pGRP1U=NULL;
    this->pGRP1IM=NULL;
}

bool GrupoOpc::excluiItensGrupo(){

    list<ItemOpc*>::iterator it;
    it = itensAdicionados.begin();
    while (it!=itensAdicionados.end()){
        //(*(*it)->getpGRP1IM())->Release();
        //(*(*it)->getpGRP1U())->Release();
        delete *it;
        it++;
    }
    itensAdicionados.clear();
    return true;
}

bool GrupoOpc::adicionaItem(char *nomeItem){
    ItemOpc *itemAdicionar = new ItemOpc(nomeItem);
    OPCITEMDEF item;
    OPCITEMRESULT *ir;
    HRESULT *ih;
    OPCHANDLE* g_sh;

    item.szItemID = WSTRFromSBCS(nomeItem, 0);
    item.szAccessPath = WSTRFromSBCS("", 0);
    item.bActive = TRUE;
    item.hClient = 100;
    item.dwBlobSize = 0;
    item.pBlob = NULL;
    item.vtRequestedDataType = VT_EMPTY;


    HRESULT hh = pGRP1IM->AddItems(1, &item, &ir, &ih);
    if (FAILED(hh)){
        return false;
    }
    if (FAILED(ih)){
        return false;
    }
    g_sh = &ir->hServer;
    itemAdicionar->setItemHandler(g_sh);
    itensAdicionados.insert(itensAdicionados.begin(),itemAdicionar);
    return true;

}

bool GrupoOpc::excluiItem(){
    itensAdicionados.erase(itensAdicionados.begin(),itensAdicionados.begin().operator ++() );
    return true;
}

bool GrupoOpc::lerItem(char* tagOpc)
{
    VARIANT v;
    HRESULT hrread;
    OPCITEMSTATE* is;
    HRESULT *hr;

    if(this->getItem(tagOpc) == NULL)
        return false;
    OPCHANDLE *oh = this->getItem(tagOpc)->getItemHandler();
    hrread = pGRP1SIO->Read(OPC_DS_CACHE, 1, oh , &is, &hr);
    if (FAILED(hrread)){
        return false;
    }
    if (FAILED(hr)) {
        return false;
    }
    v = is->vDataValue;

    if (is->wQuality == OPC_QUALITY_BAD){
        this->getItem(tagOpc)->setQualidadeItem((char *)"RUIM");
    }
    if (is->wQuality == OPC_QUALITY_UNCERTAIN) {
        this->getItem(tagOpc)->setQualidadeItem((char *)"INCERTA");
    }
    if (is->wQuality == OPC_QUALITY_GOOD){
        this->getItem(tagOpc)->setQualidadeItem((char *)"BOA");
    }
    VariantClear(&is->vDataValue);
    this->getItem(tagOpc)->setDadoItem(v);

    ::CoTaskMemFree(is);
    ::CoTaskMemFree(hr);
    return true;
}


ItemOpc* GrupoOpc::getItem(char *nomeItemBusca){
    list<ItemOpc*>::iterator it;
    it = itensAdicionados.begin();
    while (it!=itensAdicionados.end()){
        if (! strcmp((*it)->getNomeItem()  , nomeItemBusca  )  ) {
            return  (*it);
        }
        it++;
    }
    return NULL;

}

bool GrupoOpc::escreverItem(char* tagOpc,char* valor) {
    HRESULT r2;
    HRESULT *hr= NULL;
    VARIANT v;

    VariantClear(&v);
    v.vt= VT_R8;
    v.dblVal = atof(valor);
    OPCHANDLE *oh;
    if(this->getItem(tagOpc) != NULL){
        oh = this->getItem(tagOpc)->getItemHandler();
    } else{
        return false;
    }

    r2 = pGRP1SIO->Write(1, oh, &v, &hr);

    if(hr[0]==S_OK)
        if (r2!=S_OK){
        return false;
    }


    ::CoTaskMemFree(hr);
    //pIMalloc->Free(hr);
    this->getItem(tagOpc)->setDadoItem(v);
    //		delete v;
    return true;
}

